Software projects typically contain a collection of interdependent resources. For example, a source file may define a data type that extends or includes instances of one or more data types defined in other files, components or projects. Changes to a given resource may necessitate analysis or building of other resources that depend on that resource, such that the impact of the changes is reflected on the dependent resources and aspects of the given resource on which other resources depend still exists in the required form.
It is common to capture the dependencies between resources in a project in a separate file, sometimes called a “make” or “build” file. A software program (e.g., “make” or “ant”) reads the set of dependencies in the file, examines the timestamps of the resources listed in the file to determine which ones are out of date (e.g., their associated source files have been modified), and uses the set of dependencies to determine which resources should be rebuilt based on which resources are out of date. The software program then rebuilds each resource that is out of date and each resource that depends on a resource that is out of date. There also exist automated versions of this process wherein a software development environment analyzes a software project, determines the set of resource dependencies, examines resource timestamps to determine which resources are out of date, and rebuilds each resource that is out of date or depends on a resource that is out of date.
Performing a full dependency analysis of a complex project from scratch can be time consuming. In addition, most dependency analysis and build systems assume that any change to a resource requires all resources that depend on that resource to be rebuilt. In reality, it may be that only a subset of possible resource changes requires dependent resources to be rebuilt. Consequently, these dependency analysis and build systems require more time and resources to rebuild a modified project than necessary.
These inefficiencies are wasteful in some environments, but particularly troublesome for “smart” interactive software development environments that attempt to provide a highly informative, responsive editing experience while analyzing and building the project in the background. These software development environments attempt to provide accurate, up to date information about the resources being edited based on their analysis of the those resources and their dependencies. For example, a software development environment may provide syntax coloring to highlight various aspects of the language grammar (e.g., type definitions, identifiers, methods signatures, comments, etc.) used in a source file. It may provide lists of available fields and methods based on its understanding of the types being used or extended. It may highlight known errors in the resources being edited.
To provide the best user experience, these environments attempt to identify errors as close to the moment they are introduced as possible and provide timely and helpful information about the resources being edited even as the other resources they depend on are being modified e.g. in a different window, by a different user or by synchronizing with a source control system. It is not desirable for the software development environment to pause or interrupt the user's typing while it performs dependency analysis or rebuilds a set of resources. Nor is it desirable for the software development environment to introduce a lengthy delay between the time a change is made and the time the analysis of the change is presented to the user.